package yhao.infra.feature.aliyun.oss.core.request;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import yhao.infra.common.util.CommonStringUtil;
import yhao.infra.feature.aliyun.oss.core.AliyunOssBaseRequest;
import yhao.infra.feature.aliyun.oss.core.BucketInfo;
import yhao.infra.feature.aliyun.oss.core.response.AliyunOssUploadResponse;

import java.io.ByteArrayInputStream;
import java.util.UUID;

/**
 * 文件上传
 * @see <a href="https://help.aliyun.com/document_detail/84781.html?spm=a2c4g.11174283.6.784.26c77da2VVOJZ1">更多明细</a>
 */
public class AliyunOssUploadRequest extends AliyunOssBaseRequest<AliyunOssUploadResponse> {
    //上传文件大小限制
    private long fileSizeLimit;
    //字节上传的文件流
    private byte[] fileByte;
    //字节上传的文件名称
    private String originalFileName;
    //文件类型
    private String fileType;
    //文件扩展名
    private String fileExtensionName;
    //上传后的文件名
    private String uploadFileName;
    //是否使用https上传
    private boolean https = true;
    //是否为文件
    private boolean file = true;
    //是否加水印，仅图片有效
    private boolean waterMark;
    //文件路径前缀(目录，注意格式如：'pro/' 或 'pro/saas/oa/')
    private String prefix;

    public AliyunOssUploadRequest(MultipartFile file) {
        if(file == null){
            throw new IllegalArgumentException("文件上传对象不得为空");
        }
        try {
            this.fileByte = file.getBytes();
            this.originalFileName = file.getOriginalFilename();
            this.fileExtensionName = CommonStringUtil.getExtensionName(originalFileName);
            this.uploadFileName = UUID.randomUUID().toString() + "." + fileExtensionName;
            this.fileType = file.getContentType();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public AliyunOssUploadRequest() {

    }

    public void setFileByte(byte[] fileByte) {
        this.fileByte = fileByte;
    }

    public void setOriginalFileName(String originalFileName) {
        this.originalFileName = originalFileName;
        this.fileExtensionName = CommonStringUtil.getExtensionName(this.originalFileName);
        this.uploadFileName = UUID.randomUUID().toString() + "." + this.fileExtensionName;
    }

    public void setFileType(String fileType) {
        this.fileType = fileType;
    }

    public void setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
    }

    public long getFileSizeLimit() {
        return fileSizeLimit;
    }

    public void setFileSizeLimit(long fileSizeLimit) {
        this.fileSizeLimit = fileSizeLimit;
    }

    public boolean isWaterMark() {
        return waterMark;
    }

    public void setWaterMark(boolean waterMark) {
        this.waterMark = waterMark;
    }

    public byte[] getFileByte() {
        return fileByte;
    }

    public String getFileType() {
        return fileType;
    }

    public String getOriginalFileName() {
        return originalFileName;
    }

    public String getFileExtensionName() {
        return fileExtensionName;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    public boolean isHttps() {
        return https;
    }

    public void setHttps(boolean https) {
        this.https = https;
    }

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public boolean isFile() {
        return file;
    }

    public void setFile(boolean file) {
        this.file = file;
    }

    public AliyunOssUploadResponse doRequestWithCustomBucket(BucketInfo bucket) {
        return upload(bucket);
    }

    @Override
    protected AliyunOssUploadResponse doRequest() {
        if(file){
            checkFile(aliyunOssProperties.getFileSize());
            if(waterMark){
                throw new RuntimeException("通用文件上传水印字段无效");
            }
            return upload(fileBucket);
        }else{
            checkFile(aliyunOssProperties.getImgSize());
            if (waterMark) {
                return upload(protectBucket);
            } else {
                return upload(fileBucket);
            }
        }
    }

    private void checkFile(long defaultLimitSize) {
        if(fileByte==null){
            throw new RuntimeException("请设置文件数据");
        }
        if(StringUtils.isBlank(originalFileName)){
            throw new RuntimeException("请输入文件原始名称");
        }
        if (fileSizeLimit <= 0) {
            fileSizeLimit = defaultLimitSize;
        }
        long fileSize = fileByte.length / 1024;
        if (fileSize > fileSizeLimit) {
            throw new RuntimeException("上传文件大小超过最大限制");
        }
    }

    private AliyunOssUploadResponse upload(BucketInfo bucket) {
        String prefix = StringUtils.isNotBlank(this.getPrefix())?this.getPrefix():bucket.getPrefix();
        this.setUploadFileName(prefix+this.getUploadFileName());
        String key = this.getUploadFileName();
        byte[] uploadBytes = this.getFileByte();
        PutObjectRequest request = new PutObjectRequest(bucket.getName(), key, new ByteArrayInputStream(uploadBytes));
        try {
            PutObjectResult response = bucket.getOssClient().putObject(request);
            //解析上传成功的结果
            AliyunOssUploadResponse result = new AliyunOssUploadResponse(response);
            result.setFileName(key);
            result.setUrl(bucket.getUrl() + "/" + this.getUploadFileName());
            result.setFileSize(this.getFileByte().length / 1024);
            result.setOriginalFileName(this.getOriginalFileName());
            return result;
        } catch (OSSException ex) {
            throw new RuntimeException(ex.getErrorMessage());
        } catch (ClientException ex){
            throw new RuntimeException(ex.getErrorMessage());
        }
    }
}
